package com.wzc.hc.entity.tool;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BeanConverter {
    public static <T, E> List<T> converList(List<E> objects, Class<T> tClass) {
        ArrayList<T> ts = new ArrayList<>();
        objects.forEach(object -> ts.add(convertVoToPo(object, tClass)));
        return ts;
    }

    /**
     * 将VO对象转换为PO对象
     *
     * @param vo      VO对象
     * @param poClass PO对象的Class类型
     * @param <T>     PO类型
     * @return 转换后的PO对象
     */
    public static <T> T convertVoToPo(Object vo, Class<T> poClass) {
        if (vo == null) {
            return null;
        }

        try {
            // 创建PO对象
            T po = poClass.getDeclaredConstructor().newInstance();
            // 拷贝属性
            copyProperties(vo, po);
            return po;
        } catch (Exception e) {
            throw new RuntimeException("Failed to convert VO to PO", e);
        }
    }

    /**
     * 将PO对象转换为VO对象
     *
     * @param po      PO对象
     * @param voClass VO对象的Class类型
     * @param <T>     VO类型
     * @return 转换后的VO对象
     */
    public static <T> T convertPoToVo(Object po, Class<T> voClass) {
        if (po == null) {
            return null;
        }

        try {
            // 创建VO对象
            T vo = voClass.getDeclaredConstructor().newInstance();
            // 拷贝属性
            copyProperties(po, vo);
            return vo;
        } catch (Exception e) {
            throw new RuntimeException("Failed to convert PO to VO", e);
        }
    }

    /**
     * 拷贝源对象的属性到目标对象
     *
     * @param source 源对象
     * @param target 目标对象
     */
    private static void copyProperties(Object source, Object target) {
        if (source == null || target == null) {
            return;
        }

        // 获取源对象的所有字段
        Field[] sourceFields = getAllFields(source.getClass());
        // 获取目标对象的所有字段
        Field[] targetFields = getAllFields(target.getClass());

        // 遍历源对象的字段
        for (Field sourceField : sourceFields) {
            try {
                // 设置字段可访问
                sourceField.setAccessible(true);
                // 获取字段名和值
                String fieldName = sourceField.getName();
                Object fieldValue = sourceField.get(source);

                // 在目标对象中查找同名字段
                for (Field targetField : targetFields) {
                    if (targetField.getName().equals(fieldName)) {
                        // 设置字段可访问
                        targetField.setAccessible(true);
                        // 如果类型匹配，则设置值
                        if (targetField.getType().isAssignableFrom(sourceField.getType())) {
                            targetField.set(target, fieldValue);
                        }
                        break;
                    }
                }
            } catch (IllegalAccessException e) {
                throw new RuntimeException("Failed to copy properties", e);
            }
        }
    }

    /**
     * 获取类及其父类的所有字段
     *
     * @param clazz 类
     * @return 所有字段
     */
    private static Field[] getAllFields(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        Class<?> superClass = clazz.getSuperclass();
        if (superClass != null) {
            Field[] superFields = getAllFields(superClass);
            fields = concatArrays(fields, superFields);
        }
        return fields;
    }

    /**
     * 合并两个数组
     *
     * @param first  第一个数组
     * @param second 第二个数组
     * @param <T>    数组类型
     * @return 合并后的数组
     */
    private static <T> T[] concatArrays(T[] first, T[] second) {
        T[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }
}